package fi.internetix.quercus;

import java.io.IOException;
import java.sql.DriverManager;
import java.sql.SQLException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.caucho.quercus.QuercusContext;
import com.caucho.quercus.env.Env;
import com.caucho.quercus.page.QuercusPage;
import com.caucho.quercus.servlet.QuercusServletImpl;
import com.caucho.vfs.WriteStream;
import com.google.appengine.api.rdbms.AppEngineDriver;
import com.google.cloud.sql.jdbc.GoogleDataSource;

public class QuercusServlet extends com.caucho.quercus.servlet.GoogleQuercusServlet {

  private static final long serialVersionUID = 1L;

  @Override
  public void init(ServletConfig arg0) throws ServletException {
    try {
      String instanceName = arg0.getInitParameter("instanceName");
      
      AppEngineDriver driver = new AppEngineDriver();
      DriverManager.registerDriver(driver);
      GoogleDataSource googleDataSource = new GoogleDataSource(driver) {
        
      };
      googleDataSource.setInstance(instanceName);
      dataSource = new PooledDataSource(googleDataSource);
      setDatabase(dataSource);
    } catch (SQLException e) {
      throw new ExceptionInInitializerError(e);
    }

    addModule(new MailModule());
    addModule(new DateModule());

    super.init(arg0);
  }

  @Override
  protected void setInitParam(String paramName, String paramValue) throws ServletException {
    if ("instanceName".equals(paramName)) {
      // Handled in a method above
    } else {
      super.setInitParam(paramName, paramValue);
    }
  }

  @Override
  public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    super.service(request, response);
  }

  protected QuercusServletImpl getQuercusServlet(boolean isResin) {
    return new GoogleQuercusServletImpl();
  }
  
  @Override
  public void destroy() {
    dataSource.close();
  }
  
  private PooledDataSource dataSource;

  private class GoogleQuercusServletImpl extends com.caucho.quercus.servlet.GoogleQuercusServletImpl {
    
    private static final long serialVersionUID = 1L;

    @Override
    protected QuercusContext getQuercus()
    {
      synchronized (this) {
        if (_quercus == null)
          _quercus = new GoogleQuercus();
      }

      return _quercus;
    }
    
  }
  
  private class GoogleQuercus extends com.caucho.quercus.GoogleQuercus {
    @Override
    public Env createEnv(QuercusPage page, WriteStream out, HttpServletRequest request, HttpServletResponse response) {
      return new GoogleEnv(this, page, out, request, response);
    } 
  }
}